package com.mo.scopeprivilege.config.aspect;

import com.mo.scopeprivilege.annotation.QueryScope;
import com.mo.scopeprivilege.model.user.BaseDto;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;



@Aspect
@Component
public class QueryScopeControllerAspect extends AbstractAspect {


    private Object o;
    private Parameter parameter;

    @Pointcut("@annotation(com.mo.scopeprivilege.annotation.QueryScope)")
    @Override
    public void config() {

    }
    
    @Around("config()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {

        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        Object[] args = joinPoint.getArgs();
        boolean annotationPresent = method.isAnnotationPresent(QueryScope.class);
        if (!annotationPresent) {
            return joinPoint.proceed(args);
        }
        Parameter[] parameters = method.getParameters();

        for (int i = 0; i < args.length; i++) {
            if (BaseDto.class.isAssignableFrom(args[i].getClass())) {
                Field field = getField(parameters[i].getType(), "ids");
                field.setAccessible(true);
                field.set(args[i], new int[] {1, 2 });
                field.setAccessible(false);
            }
        }
        return joinPoint.proceed(args);
    }


    public Field getField(Class<?> clazz, String fieldName) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            field = null;
        }

        return field == null && !clazz.getSuperclass().equals(Object.class) ? getField(clazz.getSuperclass(), fieldName) : field;
    }
}
